package dk.hewison.util;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Iterator;


/**
 * @author John Hewison
 * @author $LastChangedBy: john.hewison $:  $ $LastChangedDate: 2009-02-09 12:39:39 +0000 (Mon, 09 Feb 2009) $:
 * @version $Revision: 363 $:
 */
public class ThumbnailCreater2 {

    public static final int BIG_THUMB = 1000;
    public static final int LITTLE_THUMB = 144;


    public static void createThumbnail(File imageFile) throws IOException {

        String suffix = getSuffix(imageFile.getName());

        ImageInputStream iis = ImageIO.createImageInputStream(imageFile);

        BufferedImage[] image = readSubsampling(iis, suffix, LITTLE_THUMB, BIG_THUMB);

        File littleThumb = new File(imageFile.getParent() + File.separator + "." + imageFile.getName().toLowerCase());
        File bigThumb = new File(imageFile.getParent() + File.separator + ".a" + imageFile.getName().toLowerCase());

        writeNewImage(image[0], littleThumb);
        writeNewImage(image[1], bigThumb);
    }

    public static BufferedImage[] readSubsampling(ImageInputStream in, String suffix, int... maxSizes) throws IOException {
        ImageReader reader = getReader(suffix);
        reader.setInput(in, true, true);
        ImageReadParam param = reader.getDefaultReadParam();

        BufferedImage[] bufferedImages = new BufferedImage[maxSizes.length];
        for (int i = 0; i < maxSizes.length; i++) {
            int maxSize = maxSizes[i];

            int size = Math.max(reader.getWidth(0), reader.getHeight(0));
            int subsampling = size / maxSize + (size % maxSize != 0 ? 1 : 0);
            param.setSourceSubsampling(subsampling, subsampling, 0, 0);
            bufferedImages[i] = reader.read(0, param);
            Log.debug("Size = " + size + ", maxSize = " + maxSize + ", w = " +
                    bufferedImages[i].getWidth() + ", h = " + bufferedImages[i].getHeight());
        }
        reader.dispose();
        return bufferedImages;
    }

    public static ImageReader getReader(String suffix) throws IOException {
        Iterator readers = ImageIO.getImageReadersBySuffix(suffix);
        if (!readers.hasNext())
            throw new IOException("No reader for suffix " + suffix);
        ImageReader reader = (ImageReader) readers.next();
        if (readers.hasNext())
            Log.debug("(There are more readers for suffix " + suffix + " )");

        return reader;
    }

    public static String getSuffix(String path) throws IOException {
        int dotIndex = path.lastIndexOf('.');
        if (dotIndex == -1)
            throw new IOException("Suffix not found for " + path);
        return path.substring(1 + dotIndex);
    }

    //-----------------writer---------------------

    public static void writeNewImage(BufferedImage image, File file) throws IOException {

        Log.debug(".writeNewImage " + file.getAbsolutePath());
        String ext = getSuffix(file.getName());
        /*if (ext.equals("jpg") || ext.equals("jpeg"))
            writeNewJpegImage(image, removeExtention(file.getCanonicalPath()), QUALITY, true);
        else*/
        ImageIO.write(image, ext, file);
    }

    /*public void writeNewImage(BufferedImage image, String filename) throws IOException {
        String ext = getExtension(filename).toLowerCase();
        if (ext.equals("jpg") || ext.equals("jpeg"))
            writeNewJpegImage(image, removeExtention(filename), QUALITY, true);
        else
            ImageIO.write(image, ext, new File(filename));
    }*/

    public void writeNewJpegImage(final BufferedImage image, final String filenameNoExtension) throws IOException {
        Log.debug(getClass().getName() + ".writeNewJpegImage " + filenameNoExtension + " image width=" +
                image.getWidth() + " image height=" + image.getHeight());
        final File file = new File(filenameNoExtension + ".jpg");
        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();

        try {
            OutputStream os = new FileOutputStream(file);
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(os);
            //JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam( image );
            //param.setWriteImageOnly( false );
            //param.setQuality( quality, false );

            //JPEGCodec.createJPEGEncoder(new FileOutputStream( file ));

            //final JPEGImageEncoder encoder = new JPEGImageEncoder( new FileOutputStream( file ), param );
            encoder.encode(image);//, param );
            os.flush();
            os.close();
        } catch (IOException e) {
            Log.debug(getClass().getName() + ".writeNewJpegImage" + e);
            //ImageIO.write( image, "jpg", file );
        }
        //ImageIO.write( thumbnailImage, "jpg", cacheFile );

        image.flush();
        //ImageInfo info = createImageInfo( file, image );
        /*if( createThumbnail && file.length() > 30000 )
        {
           cacheImage( file );
        } */
    }

    public static File writeNewJpegImage(final BufferedImage image, final String filenameNoExtension, float quality,
                                         boolean forceOverwrite) throws IOException {
        final File file = new File(filenameNoExtension + ".jpg");
        if (!forceOverwrite && file.exists())
            return file;

        if (!file.getParentFile().exists())
            file.getParentFile().mkdirs();

        try {
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(new FileOutputStream(file));
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(image);
            param.setQuality(quality, false);
            encoder.encode(image, param);
        } catch (IOException e) {
            Log.debug(".writeNewJpegImage" + e);
            e.printStackTrace();
            //ImageIO.write( image, "jpg", file );
        }
        //ImageIO.write( thumbnailImage, "jpg", cacheFile );

        image.flush();
        //ImageInfo info = createImageInfo( file, image );
        /*if( createThumbnail && file.length() > 30000 )
        {
           cacheImage( file );
        } */
        return file;
    }
}
